//编写序列化写端
#include<iostream>
#include<fstream>
#include"contacts.pb.h"                     

using namespace std;



void AddPeopleInfo(contacts2::PeopleInfo* people_info)
{
    cout << "-------------新增联系⼈-------------" << endl;
    cout << "请输入联系⼈的姓名：";
    string name;
    getline(cin, name);
    people_info->set_name(name);

    cout << "请输入联系⼈年龄：";
    int age;
    cin >> age;
    people_info->set_age(age);
    //前面用了 cin >> age; 读取一个整数后，用户输入时最后按下的回车键（\n）仍然留在输入缓冲区。
    //如果不清理掉这个残留的换行符，下一次使用 getline(cin, str) 等读取整行字符串的操作时，会直接读到这个换行符，导致读取失败或行为异常。
    //丢弃（忽略）输入缓冲区中最多 256 个字符，直到遇到换行符 '\n' 为止。
    cin.ignore(256, '\n');

    for(int i = 0; ;i++)
    {
        cout << "请输入联系⼈的电话号码 " << i+1 << "(输入回车退出): ";
        string number;
        getline(cin, number);
        if(number.empty()) break;
        contacts2::PeopleInfo_Phone* phone = people_info->add_phone_numbers();
        phone->set_number(number);
        cout << "请输入联系⼈的电话类型" << "(1:移动 2:固定): ";
        int type;
        cin >> type;
        cin.ignore(256, '\n');
        switch (type) 
        {
            case 1:
                phone->set_type(contacts2::PeopleInfo_Phone_PhoneType_M_P);
                break;
            case 2:
                phone->set_type(contacts2::PeopleInfo_Phone_PhoneType_TEL_P);
                break;
            default:
                cout << "输入错误" << endl;
                break;
        }
    }

    //添加地址
    //1.创建Address对象
    contacts2::Address address;

    //2.设置地址信息
    cout << "请输入联系⼈的家庭地址：";
    string home_address;
    getline(cin, home_address);
    address.set_home_address(home_address);

    cout << "请输入联系人办公地址：";
    string office_address;
    getline(cin, office_address);
    address.set_office_address(office_address);

    //3.将Address对象添加到PeopleInfo对象中
    //mutable_data开辟了一个新的空间，将Address对象序列化到这个空间中，然后将指针返回
    people_info->mutable_data()->PackFrom(address);

    //添加其他联系方式
    cout << "请输入联系⼈的其他联系方式" << "(1、QQ 2、微信): ";
    int other_contact;
    cin >> other_contact;
    cin.ignore(256, '\n');
    switch (other_contact) 
    {
        case 1:
        {
            string qq_number;
            cout << "请输入联系⼈的QQ号码：";
            getline(cin, qq_number);
            people_info->set_qq(qq_number);
            break;
        }
        case 2:
        {
        string wechat_id;
            cout << "请输入联系⼈的微信号：";
            getline(cin, wechat_id);
            people_info->set_wechat(wechat_id);
            break;
        }  
        default:
            cout << "输入错误" << endl;
            break;
    }

    //添加备注信息
    for(int j = 0; ;j++)
    {
        cout << "请输入联系⼈的备注信息 " << j+1 << "(标题)" << "(输入回车退出): ";
        string remark_key;
        getline(cin, remark_key);
        if(remark_key.empty()) break;
        cout << "请输入联系⼈的备注信息 " << j+1 << "(内容)" << "(输入回车退出): ";
        string remark_value;
        getline(cin, remark_value);
        people_info->mutable_remark()->insert({remark_key, remark_value});
    }
    
    cout << "-----------添加联系⼈成功-----------" << endl;
}

int main()
{
    contacts2::Contacts contacts;
    //1.读取已存在的文件，若不存在则创建一个空文件
    fstream in("contacts.bin", ios::in | ios::binary);
    if(!in) {cout << "File not exist, create a new one." << endl;}
    else{
        if(!contacts.ParseFromIstream(&in)){
            cout << "Parse file failed" << endl;
            return -1;
        }
        cout << "Parse file success" << endl;
    }

    //2.添加联系人到通讯录
    AddPeopleInfo(contacts.add_people());

    //3.将通讯录序列化到文件中
    fstream out("contacts.bin", ios::out | ios::trunc | ios::binary);
    if(!contacts.SerializeToOstream(&out)){
        cout << "Serialize file failed" << endl;
        return -1;
    }
    cout << "Serialize file success" << endl;   

    //4.关闭文件
    in.close();
    out.close();
    return 0;
}